<template>
  <q-page class="q-pa-md">
    <q-btn class="float-right" color="primary" icon="arrow_back" outline title="返回" to="/" />
    <div class="q-pb-md text-h5">入库验收</div>
    <!--错误提示-->
    <q-banner class="text-white bg-red q-mb-sm" dense inline-actions v-if="serverErrorMessage">
      {{ serverErrorMessage }}
      <template v-slot:action>
        <q-btn @click="serverErrorMessage = ''" dense flat icon="close" size="sm" />
      </template>
    </q-banner>
    <q-stepper v-model="$d.workStep" ref="stepper" color="primary" flat :header-nav="false">
      <q-step :name="1" title="单号" icon="note" :done="$d.workStep>1">
        <div class="row q-pt-sm">
          <div class="col-12">
            <q-icon color="red" name="fas fa-asterisk" size="10px" />
            <span>预定进货通知单ID</span>
            <easy-input v-model="$d.form1.asnId" :readonly="asnInfoLoadingState" @focus="fx.ui.select"
              @keyup.enter="onAsnIdEntered" :maxlength="40" autofocus ref="asnIdDom"
              :error="v_form1$.asnId.$error" :error-message="e$(v_form1$.asnId.$errors)">
            </easy-input>
          </div>
        </div>
        <div class="row q-pt-sm q-col-gutter-sm">
          <div class="col-6">
            <span>预定进货通知单号</span>
            <easy-input readonly v-model="$d.asnInfo.asnNo" />
          </div>
          <div class="col-6">
            <span>状态</span>
            <easy-input readonly :model-value="fx.fmt.fmtWmsAsnState($d.asnInfo.asnState)" />
          </div>
          <div class="col-6">
            <span>仓库</span>
            <easy-input readonly v-model="$d.asnInfo.whName" />
          </div>
          <div class="col-6">
            <span>货主</span>
            <easy-input readonly v-model="$d.asnInfo.storerAbbrName" />
          </div>
        </div>
      </q-step>
      <q-step :name="2" title="料号" icon="all_inbox" :done="$d.workStep>2">
        <div class="row q-pt-sm q-col-gutter-sm">
          <div class="col-6">
            <span>品牌</span>
            <simple-filter-select :options="$d.brandDropdownList" :use-filter="false" option-label="brandName"
              option-value="brandId" v-model="$d.brandId" :auto-select-single-option="allInFlag"
              :trigger-auto-sel-every-ops-chg="true" @update:model-value="brandIdChanged" />
          </div>
          <div class="col-6">
            <span>解码规则</span>
            <simple-filter-select :options="$d.wmBrandDecodeRuleLite"
              :use-filter="false" option-label="brandDecodeRuleName" option-value="brandDecodeRuleId" v-model="$d.brandDecodeRuleId"
              :auto-select-single-option="allInFlag && ($d.wmBrandDecodeRuleLite.length === 1)"
              :trigger-auto-sel-every-ops-chg="true" />
          </div>
          <div class="col-6">
            <span>2D</span>
            <div class="bg-grey-3">
              <q-checkbox class="full-width q-pa-xs" color="primary q-pa-xs" dense
                v-model="is2DEnabled" @input="onChanged2D" />
            </div>
          </div>
          <div class="col-6">
            <span>原厂二维码扫描</span>
            <easy-input v-model="$d.scanContent" :readonly="(!is2DEnabled) || (!$d.brandDecodeRuleId) || brandBarcodeDecodingState"
              ref="scanContent" @keyup.enter="brandBarcodeDecode" :loading="brandBarcodeDecodingState"
              :error="v_form3$.scanContent.$error" :error-message="e$(v_form3$.scanContent.$errors)" :maxlength="300" />
          </div>
          <div class="col-12">
            <q-icon color="red" name="fas fa-asterisk" size="10px" />
            <span>料号/原厂料号</span>
            <easy-input v-model="$d.skuOrSkuMf" ref="skuOrSkuMf" @keyup.enter="onSkuOrSkuMfEntered"
              :disable="skuInfoLoadingState || skuIdLoadingState" @focus="fx.ui.select"
              :error="v_form3$.skuOrSkuMf.$error" :error-message="e$(v_form3$.skuOrSkuMf.$errors)"
              @update:model-value="onSkuOrSkuMfEntered('clear')"/>
          </div>
          <div class="col-12">
            <q-icon color="red" name="fas fa-asterisk" size="10px" />
            <span>料号</span>
            <simple-filter-select :options="$d.availableSkuList" :use-filter="false" option-label="sku"
              option-value="skuId" v-model="$d.form.skuId"
              :loading="skuInfoLoadingState" @update:model-value="onSkuIdChanged"
              :error="v_form3$.form.skuId.$error" :error-message="e$(v_form3$.form.skuId.$errors)"/>
          </div>
          <div class="col-4">
            <q-icon color="red" name="fas fa-asterisk" size="10px" />
            <span>储区</span>
            <simple-filter-select :options="$d.zoneDropdownList" :use-filter="false" option-label="zoneName"
              option-value="zoneId" v-model="$d.zoneId" @update:model-value="onZoneIdChanged"
              :error="v_form3$.zoneId.$error" :error-message="e$(v_form3$.zoneId.$errors)"/>
          </div>
          <div class="col-4">
            <q-icon color="red" name="fas fa-asterisk" size="10px" />
            <span>单件装量</span>
            <simple-filter-select :options="$d.qtyPEaDropdownList" :use-filter="false" v-model="$d.form.qtyPEa"
              :error="v_form3$.form.qtyPEa.$error" :error-message="e$(v_form3$.form.qtyPEa.$errors)"/>
          </div>
          <div class="col-4">
            <q-icon color="red" name="fas fa-asterisk" size="10px" />
            <span>储位</span>
            <easy-input v-model="$d.form.loc" @focus="fx.ui.select" ref="loc"
              :error="v_form3$.form.loc.$error" :error-message="e$(v_form3$.form.loc.$errors)"
              @keyup.enter="focusHelper.onEntered(1)"/>
          </div>
          <div class="col-4">
            <q-icon color="red" name="fas fa-asterisk" size="10px" />
            <span>内盒装量</span>
            <easy-input v-model="$d.form.qtyPIip" @focus="fx.ui.select" ref="qtyPIip"
              :error="v_form3$.form.qtyPIip.$error" :error-message="e$(v_form3$.form.qtyPIip.$errors)"
              @keyup.enter="focusHelper.onEntered(2)"/>
          </div>
          <div class="col-4">
            <q-icon color="red" name="fas fa-asterisk" size="10px" />
            <span>盒装量</span>
            <easy-input v-model="$d.form.qtyPIp" @focus="fx.ui.select" ref="qtyPIp" :loading="skuIdLoadingState"
              :error="v_form3$.form.qtyPIp.$error" :error-message="e$(v_form3$.form.qtyPIp.$errors)"
              @keyup.enter="focusHelper.onEntered(3)"/>
          </div>
          <div class="col-4">
            <q-icon color="red" name="fas fa-asterisk" size="10px" />
            <span>箱装量</span>
            <easy-input v-model="$d.form.qtyPCase" @focus="fx.ui.select" :loading="skuIdLoadingState"
              :error="v_form3$.form.qtyPCase.$error" :error-message="e$(v_form3$.form.qtyPCase.$errors)"
              :ref="el=>focusHelper.regRef(el, 4)" @keyup.enter="focusHelper.onEntered(4)"/>
          </div>
          <div class="col-12">
            <span>自动创建物料包装规格</span>
            <div class="bg-grey-3">
              <q-checkbox class="full-width q-pa-xs" color="primary q-pa-xs" dense
                v-model="$d.form.autoCreateSkuPackageInfo"/>
            </div>
          </div>
          <div class="col-4">
            <q-icon color="red" name="fas fa-asterisk" size="10px" />
            <span>栈板(箱号)</span>
            <easy-input v-model="$d.form.lpn" @focus="fx.ui.select"
              :error="v_form3$.form.lpn.$error" :error-message="e$(v_form3$.form.lpn.$errors)"
              :ref="el=>focusHelper.regRef(el, 5)" @keyup.enter="focusHelper.onEntered(5)"/>
          </div>
          <div class="col-4">
            <q-icon color="red" name="fas fa-asterisk" size="10px" />
            <span>收货数量</span>
            <easy-input v-model="$d.form.qty" @focus="fx.ui.select"
              :error="v_form3$.form.qty.$error" :error-message="e$(v_form3$.form.qty.$errors)"
              :ref="el=>focusHelper.regRef(el, 6)" @keyup.enter="focusHelper.onEntered(6)"/>
          </div>
          <div class="col-4">
            <q-icon color="red" name="fas fa-asterisk" size="10px" />
            <span>包装形态</span>
            <simple-filter-select :options="fx.lst.packageTypeDropdownList" :use-filter="false" v-model="$d.form.packageType"
              :error="v_form3$.form.packageType.$error" :error-message="e$(v_form3$.form.packageType.$errors)"/>
          </div>
        </div>
      </q-step>
      <q-step :name="3" title="属性" icon="format_list_numbered" :done="$d.workStep>3">
        <div class="row q-pt-sm q-col-gutter-sm">
          <div class="col-6" v-if="$d.receiveInfo[0] && $d.receiveInfo[0].isMandatory">
            <span>毛重是否来自称重</span>
            <div class="bg-grey-3">
              <q-checkbox class="full-width q-pa-xs" color="primary q-pa-xs" dense
                v-model="$d.form.isGwWeighted" :disable="!$d.electronicScaleUrl" />
            </div>
          </div>
          <div class="col-6" v-for="(value, index) in $d.receiveInfo" :key="index"
            v-show="(index > 1) || (index <= 1 && value.isMandatory)">
            <q-icon color="red" name="fas fa-asterisk" size="10px" v-if="value.isMandatory" />
            <span>{{ value.label }}</span>
            <easy-input v-model="$d.form[value.fieldName]" @focus="fx.ui.select"
              @keyup.enter="checkDateCode(value, index + 7)" :maxlength="40" v-if="(value.fieldName !== 'gw') && (value.fieldName !== 'cube')"
              :error="v_form2$.form[value.fieldName].$error" :error-message="e$(v_form2$.form[value.fieldName].$errors)"
              :ref="el=>focusHelper.regRef(el, index + 7)"/>

            <easy-input v-model="$d.form.cube" @focus="fx.ui.select"
              @keyup.enter="checkDateCode(value,  index + 7)" :maxlength="40" v-if="value.fieldName === 'cube'"
              :error="v_form2$.form.cube.$error" :error-message="e$(v_form2$.form.cube.$errors)" />

            <q-input :hide-bottom-space="true" dense v-if="value.fieldName === 'gw'"
              no-error-icon outlined square stack-label v-model="$d.form.gw"
              :error="v_form2$.form.gw.$error" :error-message="e$(v_form2$.form.gw.$errors)"
              :ref="el=>focusHelper.regRef(el, index + 7)" @keyup.enter="focusHelper.onEntered(index + 7)">
              <template v-slot:after>
                <q-btn style="width:40px" color="primary" dense @click="onOrderWeighing"
                  :disable="!$d.electronicScaleUrl || orderWeighingState" label="称重" :loading="orderWeighingState">
                </q-btn>
              </template>
            </q-input>
          </div>
        </div>
      </q-step>
      <q-step :name="4" title="打印" icon="eva-printer">
        <div class="row q-pt-sm q-col-gutter-sm" v-for="(value, index) in $d.lblConfigs" :key="index">
          <div class="col-4">
            <q-checkbox class="full-width q-pa-xs" color="primary q-pa-xs" dense
              v-model="value.isEnabled" label="打印" />
          </div>
          <div class="col-4">
            <q-input dense outlined square stack-label readonly :model-value="fx.fmt.fmtLabelTypeDict(value.labelType)">
            </q-input>
          </div>
          <div class="col-4">
            <q-input dense outlined square stack-label readonly :model-value="value.lblName">
            </q-input>
          </div>
          <div class="col-6">
            <span>验收数量</span>
            <q-input :hide-bottom-space="true" dense clearable no-error-icon outlined square stack-label
              v-model="value.qtyForReceived" @focus="fx.ui.select" @input="onQtyForReceivedChanged(value)"
              :error="v_form4$[index].qtyForReceived.$error" :error-message="e$(v_form4$[index].qtyForReceived.$errors)">
            </q-input>
          </div>
          <div class="col-6">
            <span>标签数量</span>
            <q-input :hide-bottom-space="true" dense clearable no-error-icon outlined square stack-label
              v-model="value.labelCount" @focus="fx.ui.select"
              :error="v_form4$[index].labelCount.$error" :error-message="e$(v_form4$[index].labelCount.$errors)">
            </q-input>
          </div>
          <div class="col-6">
            <span>副本</span>
            <q-input :hide-bottom-space="true" dense clearable no-error-icon outlined square stack-label
              v-model="value.printNum" @focus="fx.ui.select"
              :error="v_form4$[index].printNum.$error" :error-message="e$(v_form4$[index].printNum.$errors)">
            </q-input>
          </div>
          <div class="col-6">
            <span>打印机编号</span>
            <q-input dense clearable no-error-icon outlined square stack-label v-model="value.printerNo"
              @focus="fx.ui.select">
            </q-input>
          </div>
          <div class="col-12">
            <q-separator />
          </div>
        </div>
      </q-step>
      <template v-slot:navigation>
        <div class="row q-pt-md q-col-gutter-sm">
          <!-- Step1的按钮 -->
          <div class="offset-6 col-6" v-show="$d.workStep===1">
            <q-btn :disable="!isValidAsnForReceive" class="full-width" color="primary" icon-right="arrow_forward"
              label="下一步" @click="onNext1" />
          </div>
          <!-- Step2的按钮 -->
          <div class="col-6" v-show="$d.workStep===2">
            <q-btn class="full-width" color="primary" icon="arrow_back" label="上一步" outline @click="$d.workStep=1" />
          </div>
          <div class="col-6" v-show="$d.workStep===2">
            <q-btn class="full-width" color="primary" icon-right="arrow_forward" label="下一步" @click="onNext2"
              :loading="receiveInfoLoadingState" />
          </div>
          <!-- Step3的按钮 -->
          <div class="col-6" v-show="$d.workStep===3">
            <q-btn class="full-width" color="primary" icon="arrow_back" label="上一步" outline @click="lastStep3" />
          </div>
          <div class="col-6" v-show="$d.workStep===3">
            <q-btn class="full-width" color="primary" icon-right="fas fa-sign-in-alt" label="入库"
              @click="receiveGoodsByPda" :loading="submitingState" />
          </div>
          <!-- Step4的按钮 -->
          <div class="col-6" v-show="$d.workStep===4">
            <q-btn class="full-width" color="primary" label="不打印" @click="doneThenGoBack" outline />
          </div>
          <div class="col-6" v-show="$d.workStep===4">
            <q-btn class="full-width" color="primary" label="打印" @click="doPrintLabel" :disable="canPrintLabel" />
          </div>
        </div>
      </template>
    </q-stepper>

    <q-dialog persistent transition-hide="none" transition-show="none" v-model="showingPrintLabelDlg">
      <q-card style="max-width: 300px; width: 100%">
        <q-card-section>
          <div class="text-h6 text-center">打印中... {{ $d.printedNum }}/{{ printSum }}</div>
        </q-card-section>
        <q-separator class="separator" />
        <q-card-actions align="center">
          <q-btn color="primary" label="中止" outline unelevated v-close-popup @click="printLabelCancelled" />
        </q-card-actions>
      </q-card>
    </q-dialog>
  </q-page>
</template>

<script lang="ts">
export default {
  name: 'AsnReceiveStd'
}
</script>

<script lang="ts" setup>
import {computed, nextTick, reactive, ref} from 'vue'
import useVuelidate, {ValidationArgs} from '@vuelidate/core'
import {WmAsn} from '@njt/wms/defs/work/asn'
import {playBeepSound, playErrorSound, playSuccessSound} from '@njt/wms/helper/audio'
import {
  BarcodeDecodeRuleInfo,
  DecodableBrandInfo,
  ReceiveGoodsByPdaReq,
  WmBrandLite,
  WmBrandDecodeRuleLite
} from '../../defs/asnReceive'
import {QInput} from 'quasar'
import {WmSku, WmSkuLiteForAsnRecv} from '@njt/wms/defs/basic/sku'
import {WmZoneLite} from '@njt/wms/defs/basic/zone'
import _ from 'lodash'
import {WmPackage} from '@njt/wms/defs/basic/package'
import {LacrAttr} from '@njt/wms/defs/work/order'
import Decimal from 'decimal.js'
import {ReceiveInfoBySkuAndAsn} from '@njt/wms/defs/rule/ruleConfig'
import dayjs from 'dayjs'
// import weekOfYear from 'dayjs/plugin/weekOfYear'
import {WmInvLotAttr} from '@njt/wms/defs/inventory/lotattr'
import {ReceiveGoodsByPdaResp, LblConfigByPda} from '@njt/wms/defs/work/pda'
import {useCollectionValHelper} from '@njt/foundation/hooks/collectionValHelper'
import {useFocusNextHelper} from '@njt/foundation/hooks/focusHelper'
import { date } from 'quasar'

// dayjs.extend(weekOfYear)

let $d = reactive({
  brandDecodeRuleId: null as number | null,
  wmBrandDecodeRuleLite: [] as WmBrandDecodeRuleLite[],
  // 作业步骤
  workStep: 1,
  // 表单数据
  form1: {
    // ASN ID
    asnId: null,
  },
  // 表单数据
  form: {
    autoCreateSkuPackageInfo: true,
    isGwWeighted: false
  } as ReceiveGoodsByPdaReq,
  // 通过asnId获取到asnInfo,把这些信息显示出来
  asnInfo: {} as WmAsn,
  // 品牌下拉
  brandDropdownList: [] as WmBrandLite[],
  // 品牌
  brandId: null as string | null,
  // 料号或原厂料号(界面输入)
  skuOrSkuMf: null as string | null,
  //可选SKU列表
  availableSkuList: [] as WmSkuLiteForAsnRecv[],
  // 储区
  zoneId: null as number | null,
  // 储区下拉
  zoneDropdownList: [] as WmZoneLite[],
  // 原厂二维码
  scanContent: null as string | null,
  // asnLine 体积
  totalCube: null as number | null | undefined,
  // asnLine 毛重
  totalGw: null as number | null,
  // asnLine 数量
  totalQty: null as number | null,
  // 单件装量下拉
  qtyPEaDropdownList: [] as number[],
  // 当前规则
  receiveInfo: [] as LacrAttr[],
  // 电子秤地址
  electronicScaleUrl: null as string | null,
  // NLP地址
  nlpUrl: '',
  //相关打印标签信息
  lblConfigs: [] as LblConfigByPda[],
  // 打印传递的数据
  invLotAttr: {} as WmInvLotAttr,
  // 已打印数量
  printedNum: 0,
})

const validators = $f.validators

// 单号表单验证
const rules = {
  asnId: {
    required: validators.required,
    integer: validators.int32,
    greater_than: validators.greaterThan(0)
  },

}
const v_form1$ = useVuelidate(rules, computed(() => $d.form1), {$autoDirty: true, $scope: false})
// 错误提示
let serverErrorMessage = ref('')
// 是否处于加载ASN状态中
let asnInfoLoadingState = ref(false)
let asnIdDom = ref<QInput | null>(null)
// 预定进货通知单输入
const onAsnIdEntered = () => {
  $d.skuOrSkuMf = null
  $d.availableSkuList = []
  resetAsnInfo()
  resetForm()
  $d.form.loc = null
  $d.form.lpn = null
  serverErrorMessage.value = ''
  void v_form1$.value.$validate().then((valRes) => {
    if (valRes) {
      asnInfoLoadingState.value = true
      let workState = 1
      void $f.axios.get<WmAsn>('/wms/work/asn/get-asn-by-id/' + String($d.form1.asnId).trim())
        .then((resp) => {
          $f.fmt.fmtWmsAsnState($d.asnInfo.asnState)
          $d.asnInfo = resp.data
          if (!(resp.data.asnState === '60' || resp.data.asnState === '91')) {
            playErrorSound()
            serverErrorMessage.value = '预定进货通知单状态必须为“点收完成”或“验收中”，才可以进行验收操作,该预定进货通知单状态不符合'
          } else {
            $d.form.asnId = $d.asnInfo.asnId
            workState = 2
            return $f.axios.get<DecodableBrandInfo>('/wms/basic/brand/get-decodable-brands-of-asn/' + String(resp.data.asnId))
          }
        })
        .then((resp) => {
          if (resp) {
            allInFlag.value = resp.data.allInFlag
            $d.brandDropdownList = resp.data.brandInfos
          }
        })
        .catch((err) => {
          playErrorSound()
          if (err.response?.status === 404 && workState === 1) {
            serverErrorMessage.value = '该预定进货通知单ID不存在'
          } else if (workState === 1) {
            serverErrorMessage.value = $f.getAxiosErrMsg(err)
          } else if (workState === 2) {
            $f.ui.showNotifyFailed($f.getAxiosErrMsg(err))
          }
        })
        .finally(() => {
          asnInfoLoadingState.value = false
          void nextTick(() => {
            asnIdDom.value && asnIdDom.value.focus()
          })
        })
    }
  })

}
let isValidAsnForReceive = computed(() => {
  return $d.asnInfo && $d.asnInfo.asnNo && (($d.asnInfo.asnState === '60') || ($d.asnInfo.asnState === '91'))
})
// 启用二维码扫描
let is2DEnabled = ref(true)
// 是否所有的品牌都存在解码规则
let allInFlag = ref(false)
let scanContent = ref<QInput | null>(null)
let skuOrSkuMf = ref<QInput | null>(null)
let qtyPIip = ref<QInput | null>(null)
let qtyPIp = ref<QInput | null>(null)
let loc = ref<QInput | null>(null)
// 第一页下一步
const onNext1 = () => {
  v_form2$.value.$reset()
  $d.form.autoCreateSkuPackageInfo = false
  $d.workStep = 2
  if (is2DEnabled.value && allInFlag.value && $d.brandDropdownList.length === 1) {
    void nextTick(() => {
      scanContent.value && scanContent.value.focus()
    })
  } else {
    void nextTick(() => {
      skuOrSkuMf.value && skuOrSkuMf.value.focus()
    })
  }
}
// 2D变动
const onChanged2D = (val: boolean) => {
  window.localStorage.setItem('pda:asn:is-2d-checked', String(val))
}
// 原厂二维码状态
let brandBarcodeDecodingState = ref(false)
const valResult2 = reactive({
  scanContent: '',
  skuOrSkuMf: '',
  form: {
    loc: ''
  }
})
let rules_d = {
  scanContent: {
    alwaysRight: validators.alwaysRight
  },
  skuOrSkuMf: {
    required: validators.required
  },
  zoneId: {
    required: validators.required
  },
  form: {
    skuId: {
      required: validators.required
    },
    qtyPEa: {
      required: validators.required
    },
    loc: {
      required: validators.required
    },
    qtyPIip: {
      required: validators.required,
      int32: validators.int32,
      greater_than: validators.greaterThan(0)
    },
    qtyPIp: {
      required: validators.required,
      int32: validators.int32,
      greater_than: validators.greaterThan(0),
      is_multiply: validators.isMultiply(computed(() => $d.form.qtyPIip))
    },
    qtyPCase: {
      required: validators.required,
      int32: validators.int32,
      greater_than: validators.greaterThan(0),
      is_multiply: validators.isMultiply(computed(() => $d.form.qtyPIp))
    },
    lpn: {
      required: validators.required,
    },
    qty: {
      required: validators.required,
      int32: validators.int32,
      is_multiply: validators.isMultiply(computed(() => $d.form.qtyPIip))
    },
    packageType: {
      required: validators.required,
    }
  }
}
const valResult3 = reactive({
  scanContent: '',
  skuOrSkuMf: '',
  form: {
    loc: ''
  }
})
let rules_d3 = {
  scanContent: {
    alwaysRight: validators.alwaysRight
  },
  skuOrSkuMf: {
    required: validators.required
  },
  zoneId: {
    required: validators.required
  },
  form: {
    skuId: {
      required: validators.required
    },
    qtyPEa: {
      required: validators.required
    },
    loc: {
      required: validators.required
    },
    qtyPIip: {
      required: validators.required,
      int32: validators.int32,
      greater_than: validators.greaterThan(0)
    },
    qtyPIp: {
      required: validators.required,
      int32: validators.int32,
      greater_than: validators.greaterThan(0),
      is_multiply: validators.isMultiply(computed(() => $d.form.qtyPIip))
    },
    qtyPCase: {
      required: validators.required,
      int32: validators.int32,
      greater_than: validators.greaterThan(0),
      is_multiply: validators.isMultiply(computed(() => $d.form.qtyPIp))
    },
    lpn: {
      required: validators.required,
    },
    qty: {
      required: validators.required,
      int32: validators.int32,
      is_multiply: validators.isMultiply(computed(() => $d.form.qtyPIip))
    },
    packageType: {
      required: validators.required,
    }
  }
}
let v_form2$ = useVuelidate(rules_d , computed(() => $d), {$autoDirty: true, $externalResults: valResult2, $scope: false})
let v_form3$ = useVuelidate(rules_d3 , computed(() => $d), {$autoDirty: true, $externalResults: valResult3, $scope: false})

// 品牌解码
const brandBarcodeDecode = () => {
  if ($d.brandDecodeRuleId && $d.scanContent) {
    let params = {
      brandDecodeRuleId: $d.brandDecodeRuleId,
      scanContent: $d.scanContent
    }
    brandBarcodeDecodingState.value = true
    void $f.axios.post<BarcodeDecodeRuleInfo>('/wms/basic/brand/brand-barcode-decode', params)
      .then((resp) => {
        $d.form.lpn = resp.data.lpn
        $d.form.qty = resp.data.qty
        $d.form.qtyPCase = resp.data.qtyPCase
        $d.skuOrSkuMf = resp.data.sku
        $d.form.vLot = resp.data.vLot
        $d.form.coo = resp.data.coo
        $d.form.expiredDt = resp.data.expiredDt
        $d.form.lotAttr01 = resp.data.lotAttr01
        $d.form.lotAttr02 = resp.data.lotAttr02
        $d.form.lotAttr03 = resp.data.lotAttr03
        $d.form.lotAttr04 = resp.data.lotAttr04
        $d.form.lotAttr05 = resp.data.lotAttr05
        $d.form.lotAttr06 = resp.data.lotAttr06
        $d.form.lotAttr07 = resp.data.lotAttr07
        $d.form.lotAttr08 = resp.data.lotAttr08
        $d.form.lotAttr09 = resp.data.lotAttr09
        $d.form.lotAttr10 = resp.data.lotAttr10
        $d.form.lotAttr11 = resp.data.lotAttr11
        $d.form.lotAttr12 = resp.data.lotAttr12
        $d.form.lotAttr13 = resp.data.lotAttr13
        $d.form.lotAttr14 = resp.data.lotAttr14
        $d.form.lotAttr15 = resp.data.lotAttr15
        $d.form.lotAttr16 = resp.data.lotAttr16
        $d.form.lotAttr17 = resp.data.lotAttr17
        $d.form.lotAttr18 = resp.data.lotAttr18
        $d.form.lotAttr19 = resp.data.lotAttr19
        $d.form.lotAttr20 = resp.data.lotAttr20
        if ($d.skuOrSkuMf) {
          onSkuOrSkuMfEntered()
        }
      })
      .catch((err) => {
        playErrorSound()
        valResult2.scanContent = $f.getAxiosErrMsg(err)
      })
      .finally(() => {
        brandBarcodeDecodingState.value = false
      })
  }
}
// 是否处于加载SKU状态中
let skuInfoLoadingState = ref(false)
// 错误标志位
let errorFlag = ref(false)
// 料号/原厂料号回车
const onSkuOrSkuMfEntered = (val?: string) => {
  serverErrorMessage.value = ''
  $d.availableSkuList = []
  resetForm2()
  if (val === 'clear') {
    return
  }
  if ($d.skuOrSkuMf) {
    $d.skuOrSkuMf = $d.skuOrSkuMf.trim()
    let params = {
      asnId: $d.asnInfo.asnId,
      sku: $d.skuOrSkuMf
    }
    skuInfoLoadingState.value = true
    errorFlag.value = false
    $f.axios.get<WmSkuLiteForAsnRecv[]>('/wms/work/asn/get-sku-lite-list-by-asn-and-sku', {params})
      .then((resp) => {
        if (resp.data.length === 0) {
          playErrorSound()
          valResult2.skuOrSkuMf = '未查询到该料号/原厂料号'
          errorFlag.value = true
          return
        }
        $d.availableSkuList = resp.data
        //默认选择第一个
        $d.form.skuId = resp.data[0].skuId
        onSkuIdChanged(resp.data[0].skuId)
      })
      .catch((err) => {
        playErrorSound()
        serverErrorMessage.value = $f.getAxiosErrMsg(err)
      })
      .finally(() => {
        skuInfoLoadingState.value = false
        if (errorFlag.value) {
          void nextTick(() => {
            skuOrSkuMf.value && skuOrSkuMf.value.focus()
          })
        } else if ($d.form.loc) {
          void nextTick(() => {
            qtyPIip.value && qtyPIip.value.focus()
          })
        } else {
          void nextTick(() => {
            loc.value && loc.value.focus()
          })
        }
      })
  }
}
// 切换skuId的时候的加载状态
let skuIdLoadingState = ref(false)
// 料号选择更改
const onSkuIdChanged = (val: number) => {
  serverErrorMessage.value = ''
  resetForm2()
  $d.form.skuId = val
  if (!val) return
  // 更新毛重/体积/数量
  let index = _.findIndex($d.availableSkuList, (o) => {
    return o.skuId === val
  })
  $d.totalQty = $d.availableSkuList[index].totalQty
  $d.totalGw = $d.availableSkuList[index].totalGw === null ? (Number($d.availableSkuList[index].gw) * Number($d.availableSkuList[index].totalQty)) : $d.availableSkuList[index].totalGw
  $d.totalCube = $d.availableSkuList[index].cube
  skuIdLoadingState.value = true
  // 获取三个数值/包装形态
  getSkuById(val)
    .then((resp) => {
      return getPackageById(resp)
    })
    .then((resp) => {
      $d.form.qtyPIip = resp.qtyPIip
      $d.form.qtyPIp = resp.qtyPIp

      if (!$d.scanContent) {
        $d.form.qtyPCase = resp.qtyPCase
      }
      $d.form.packageType = resp.packageType
      let params = {
        asnId: $d.asnInfo.asnId,
        skuId: $d.form.skuId
      }
      return $f.axios.get<WmZoneLite[]>('/wms/work/asn/get-zones-by-asn-id-and-sku-id', { params })
    })
    .then((resp) => {
      if (resp) {
        $d.zoneDropdownList = resp.data
        if ($d.zoneId && (resp.data.length === 1) && ($d.zoneId !== resp.data[0].zoneId)) {
          $d.zoneId = resp.data[0].zoneId
          $d.form.loc = resp.data[0]?.tempLoc ?? null
          getQtyPEas()
        } else if (resp.data.length !== 1) {
          $d.zoneId = null
          $d.form.loc = null
        } else if (resp.data.length === 1) {
          $d.zoneId = resp.data[0].zoneId
          $d.form.loc = resp.data[0]?.tempLoc ?? null
          getQtyPEas()
        }
      }
    })
    .catch((err) => {
      playErrorSound()
      serverErrorMessage.value = $f.getAxiosErrMsg(err)
    })
    .finally(() => {
      skuIdLoadingState.value = false
    })
}
const getSkuById = (id: number) => {
  return new Promise<number>((resolve, reject) => {
    $f.axios.get<WmSku>('/wms/basic/sku/get-sku-by-id/' + String(id))
      .then((resp) => {
        resolve(resp.data.packageId)
      })
      .catch((err) => {
        reject(err)
      })
  })
}
const getPackageById = (id: number) => {
  return new Promise<WmPackage>((resolve, reject) => {
    $f.axios.get<WmPackage>('/wms/basic/package/get-package-by-id/' + String(id))
      .then((resp) => {
        resolve(resp.data)
      })
      .catch((err) => {
        reject(err)
      })
  })
}
const onZoneIdChanged = (val: string) => {
  if (!val) {
    $d.form.qtyPEa = null
    return
  }
  getQtyPEas()
}
// 获取单件装量
const getQtyPEas = () => {
  let params = {
    asnId: $d.asnInfo.asnId,
    skuId: $d.form.skuId,
    zoneId: $d.zoneId
  }
  $f.axios.get<number[]>('/wms/work/asn/get-qty-p-eas-by-receive-info', { params })
    .then((resp) => {
      $d.qtyPEaDropdownList = resp.data
      if ($d.qtyPEaDropdownList.length === 1) {
        $d.form.qtyPEa = $d.qtyPEaDropdownList[0]
      }
    })
    .catch((err) => {
      $f.ui.showNotifyFailed($f.getAxiosErrMsg(err))
    })
}
// 重置form中的值
const resetForm = () => {
  $f.misc.setPropertiesToNull($d.form, ['asnId', 'loc', 'lpn'])
  $d.form.isGwWeighted = false
  $d.zoneId = null
  $d.zoneDropdownList = []
}

const resetForm2 = () => {
  $d.form.qtyPEa = null
  $d.form.loc = null
  $d.form.qtyPIip = null
  $d.form.qtyPIp = null
  $d.form.packageType = null
  $d.form.autoCreateSkuPackageInfo = false
  // $f.misc.setPropertiesToNull($d.form, ['asnId', 'loc', 'lpn'])
  $d.form.isGwWeighted = false
  $d.zoneId = null
  $d.zoneDropdownList = []
}

const resetAsnInfo = () => {
  $f.misc.setPropertiesToNull($d.asnInfo)
  allInFlag.value = false
  $d.brandDecodeRuleId = null
  $d.wmBrandDecodeRuleLite = []
  $d.brandId = null
  $d.brandDropdownList = []
  $d.scanContent = null
  $d.zoneId = null
  $d.zoneDropdownList = []
}
// 提交按钮状态
let receiveInfoLoadingState = ref(false)
// 点击第二页下一步
const onNext2 = () => {
  serverErrorMessage.value = ''
  receiveInfoLoadingState.value = true
  void Promise.resolve()
    // @ts-ignore
    .then(() => {
      if ($d.form.loc) {
        let params = {
          whId: $d.asnInfo.whId,
          loc: $d.form.loc,
          zoneId: $d.zoneId
        }
        return $f.axios.get<boolean>('/wms/basic/loc/check-if-loc-valid', { params })
      } else {
        return Promise.resolve('next')
      }
    })
    .then((resp) => {
      // @ts-ignore
      if (resp === 'next' || resp.data) {
        return v_form3$.value.$validate()
      } else {
        playErrorSound()
        valResult3.form.loc = '储位在指定的储区中不存在或已被停用'
        return Promise.reject()
      }
    })
    .then((valResult) => {
      if (valResult) {
        let params = {
          skuId: $d.form.skuId,
          asnId: $d.form.asnId
        }
        return $f.axios.get<LacrAttr[]>('/wms/work/asn/get-receive-info-by-sku-and-asn', { params })
      } else {
        return Promise.reject()
      }
    })
    .then((resp) => {
      resp.data.forEach((item) => {
        if (item.fieldName) {
          if (item.fieldName === 'cube' || item.fieldName === 'gw') {
            rules_d.form[item.fieldName] = {
              greaterThan: validators.greaterThan(0),
              decimal: validators.decimal(3),
              required: validators.requiredIf(computed(() => item.isMandatory && ($d.workStep === 3)))
            }
          } else {
            rules_d.form[item.fieldName] = getLotAttrValidationRule(item)
          }
        }
      })
      v_form2$ = useVuelidate(rules_d , computed(() => $d), {$autoDirty: true, $externalResults: valResult2, $scope: false})
      $d.receiveInfo = resp.data
      if (_.isFinite($d.totalGw) && _.isFinite($d.totalQty)) {
        let flag = _.find($d.receiveInfo, function(o) {
          return o.fieldName === 'gw'
        })
        if (flag && flag.isMandatory && $d.totalQty && $d.totalGw && $d.form.qty) {
          $d.form.gw = Number(new Decimal($d.totalGw).mul(new Decimal($d.form.qty)).div(new Decimal($d.totalQty)).roundTo(3))
        }
      } else {
        $d.form.gw = null
      }
      if ($d.totalCube) {
        $d.form.cube = Number($d.totalCube.toFixed(3))
      }
      $d.workStep = 3
    })
    .catch((err) => {
      playErrorSound()
      serverErrorMessage.value = $f.getAxiosErrMsg(err)
    })
    .finally(() => {
      receiveInfoLoadingState.value = false
    })
}

const getLotAttrValidationRule = (row: ReceiveInfoBySkuAndAsn) => {
  let regex = row.formatRestrict as string | RegExp
  // 对制造日期的验证有特殊处理
  if (row.fieldName === 'dateCode') {
    if (regex === 'yyyyMMdd') {
      regex = /^((19|20)[0-9]{2})((0[1-9])|(1[0-2]))((0[1-9])|((1|2)[0-9])|(3[0-1]))$/
    } else if (regex === 'yyyyWW') {
      regex = /^((19|20)[0-9]{2})(0[1-9]|[1-4][0-9]|5[0-3])$/
    } else {
      regex =
        /^((19|20)[0-9]{2})((0[1-9])|(1[0-2]))((0[1-9])|((1|2)[0-9])|(3[0-1]))$|^((19|20)[0-9]{2})(0[1-9]|[1-4][0-9]|5[0-3])$/
    }
  }
  return {
    regex: validators.regex(regex?RegExp(regex):RegExp('')),
    required: validators.requiredIf(row.isMandatory && ($d.workStep === 3)),
    multi_fmt_date: row.fieldName === 'expiredDt' ? validators.multiFmtDate : validators.alwaysRight,
  }
}

const checkDateCode = (row: ReceiveInfoBySkuAndAsn, index: number) => {
  let regex = row.formatRestrict
  if (row.fieldName === 'dateCode') {
    if (regex === 'yyyyMMdd') {
      if (String($d.form.dateCode).length === 6) {
        $d.form.dateCode = dateCodeFormat(String($d.form.dateCode), 6) as string
      }
      focusHelper.onEntered(index)
    } else if (regex === 'yyyyWW') {
      if (String($d.form.dateCode).length === 8) {
        $d.form.dateCode = dateCodeFormat(String($d.form.dateCode), 8) as string
      }
      focusHelper.onEntered(index)
    }
  } else {
    focusHelper.onEntered(index)
  }
}

const PrefixInteger = function (num: string, n: number) {
  return (Array(n).join('0') + num).slice(-n)
}

const dateCodeFormat = function (dateCode: string, dateCodeLength: number) {
  let year = dateCode.substring(0, 4)
  if (dateCodeLength === 6) {
    let week = dateCode.substring(4, 6)
    return dayjs(year + '-01-01').add(Number(week), 'week').format('YYYYMMDD')
  } else if (dateCodeLength === 8) {
    let newDate = new Date(Number(year), Number(dateCode.substring(4, 6)) - 1, Number(dateCode.substring(6, 8)))
    return year + PrefixInteger(String(date.getWeekOfYear(newDate)), 2)
  }
}
// 称重执行状态
let orderWeighingState = ref(false)
const onOrderWeighing = () => {
  if ($d.electronicScaleUrl) {
    orderWeighingState.value = true
    $f.axios.get<number>($d.electronicScaleUrl)
      .then((resp) => {
        $d.form.isGwWeighted = true
        playBeepSound()
        $d.form.gw = resp.data
      })
      .catch((err) => {
        playErrorSound()
        $f.ui.showNotifyFailed($f.getAxiosErrMsg(err))
      })
      .finally(() => {
        orderWeighingState.value = false
      })
  }
}
// 是否处于提交状态
let submitingState = ref(false)
// 本ASN是否验收完成
let isDoneAccepted = ref(false)
// 本次PDA验收的数量
let qtyForReceived = ref(0)
// 入库
const receiveGoodsByPda = () => {
  serverErrorMessage.value = ''
  $d.form.locId = 0
  void v_form2$.value.$validate()
    .then((valResult) => {
      if (valResult) {
        submitingState.value = true
        let receiveGoodsByPdaResp
        $f.axios
          .post<ReceiveGoodsByPdaResp>('/wms/work/asn/receive-goods-by-pda', $d.form)
          .then((resp) =>{
            isDoneAccepted.value = resp.data.isDoneAccepted
            receiveGoodsByPdaResp = resp
            let lblConfigs = resp.data.lblConfigs
            qtyForReceived.value = resp.data.qtyForReceived
            _.forEach(lblConfigs, (v) => {
              v['qtyForReceived'] = resp.data.qtyForReceived
            })
            showNotify()
            let nlpUrl = $d.nlpUrl
            if (lblConfigs.length > 0 && nlpUrl) {
              // 入库标签打印方法
              toPrintStep(lblConfigs, receiveGoodsByPdaResp.data.isDoneAccepted, resp.data.invLotAttr)
            } else {
              doneThenGoBack()
            }
          })
          .catch((err) => {
            if (err.response?.data?.errorList?.length) {
              $f.ui.showErrorListDlg(err?.response?.data)
            } else {
              serverErrorMessage.value = $f.getAxiosErrMsg(err)
            }
          })
          .finally(() =>{
            submitingState.value = false
          })
      }
    })
}

// 跳转标签打印页处理
const toPrintStep = (lblConfigs: LblConfigByPda[], isDoneAccepted$: boolean, invLotAttr: WmInvLotAttr) => {
  _.forEach(lblConfigs, (v) => {
    v.labelCount = Math.ceil(Number($d.form.qty) / Number($d.form.qtyPCase))
    v.printNum = 1
  })
  $d.lblConfigs = lblConfigs
  isDoneAccepted.value = isDoneAccepted$
  $d.invLotAttr = invLotAttr
  $d.workStep = 4
}

// 完成后跳转
const doneThenGoBack = () => {
  if (isDoneAccepted.value) {
    resetAsnInfo()
    $d.form1.asnId = null
    $d.workStep = 1
  } else {
    $d.skuOrSkuMf = null
    $d.availableSkuList = []
    $d.workStep = 2
    $d.scanContent = null
    if (is2DEnabled.value && $d.brandId) {
      void nextTick(() => {
        scanContent.value && scanContent.value.focus()
      })
    } else {
      void nextTick(() => {
        skuOrSkuMf.value && skuOrSkuMf.value.focus()
      })
    }
    resetForm()
  }
}

// 完成后提示
const showNotify = () => {
  if (isDoneAccepted.value) {
    $f.ui.showNotifySucceeded('预定进货通知单 [' + $d.form.asnId + '] 全部入库完成')
    playSuccessSound()
  } else {
    $f.ui.showNotifySucceeded('入库成功, 数量: ' + qtyForReceived.value)
    playSuccessSound()
  }
}

let canPrintLabel = computed(() => {
  return _.filter($d.lblConfigs, (o) => {
    return o.isEnabled
  }).length === 0
})
// 打印总数
let printSum = computed(() => {
  let sum = 0
  _.forEach($d.lblConfigs, (v) => {
    if (v.isEnabled) sum += Number(v.labelCount)
  })
  return sum
})


const getRulesForLine: (line: LblConfigByPda) => ValidationArgs = (line: LblConfigByPda) => {
  return {
    labelCount: {
      int32: validators.int32,
      greaterThan: validators.greaterThan(0),
      required: line.isEnabled ? validators.required : validators.alwaysRight,
      isDivisible: line.isEnabled ? validators.isDivisible(computed(() => {
        return line.qtyForReceived
      })) : validators.alwaysRight
    },
    qtyForReceived: {
      int32: validators.int32,
      greaterThan: validators.greaterThan(0),
      required: line.isEnabled ? validators.required : validators.alwaysRight
    },
    printNum: {
      int32: validators.int32,
      greaterThan: validators.greaterThan(0),
      required: line.isEnabled ? validators.required : validators.alwaysRight
    }
  }
}

const collValSuite = useCollectionValHelper(computed(() => $d.lblConfigs), getRulesForLine)

let v_form4$ = collValSuite.valObjs
// 打印提示框
let showingPrintLabelDlg = ref(false)
// 是否取消发起请求
let isPrintLabelCancelled = ref(false)
// 中止
const printLabelCancelled = () => {
  isPrintLabelCancelled.value = true
}
// 打印
const doPrintLabel = () => {
  void collValSuite.validate()
    .then((valResult) => {
      if (valResult) {
        serverErrorMessage.value = ''
        $d.printedNum = 0
        isPrintLabelCancelled.value = false
        showingPrintLabelDlg.value = true
        printInBoxLabelRecursive(0, 0)
      } else {
        playErrorSound()
      }
    })
}
// 递归打印
const printInBoxLabelRecursive = (lblConfigsIdx: number, labelIdx: number) => {
  if (isPrintLabelCancelled.value) {
    return
  }
  if (lblConfigsIdx >= $d.lblConfigs.length) {
    showingPrintLabelDlg.value = false
    doneThenGoBack()
    return
  }
  if (labelIdx >= $d.lblConfigs[lblConfigsIdx].labelCount) {
    printInBoxLabelRecursive(lblConfigsIdx + 1, 0)
    return
  }
  if (!$d.lblConfigs[lblConfigsIdx].isEnabled) {
    printInBoxLabelRecursive(lblConfigsIdx + 1, 0)
  } else {
    $d.invLotAttr['qtyForReceived'] = $d.lblConfigs[lblConfigsIdx].qtyForReceived
    let formParams = $f.misc.makeSimpleFormObj($d.invLotAttr,['lacrInfo'])
    formParams['qty'] = (qtyForReceived.value as number) / $d.lblConfigs[lblConfigsIdx].labelCount
    formParams['userId'] = $f.ua?.value.userName
    formParams['userName'] = $f.ua?.value.realName
    formParams['loc'] = $d.form.loc
    let paramsForPrint = {
      LabelName: $d.lblConfigs[lblConfigsIdx].lblName,
      PrinterName: $d.lblConfigs[lblConfigsIdx].printerNo,
      Parameters: formParams,
      PrintNum: $d.lblConfigs[lblConfigsIdx].printNum
    }
    //发送NLP
    $f.axios
      .post($d.nlpUrl, paramsForPrint)
      .then(() => {
        setTimeout(() => {
          $d.printedNum += 1
          printInBoxLabelRecursive(lblConfigsIdx, labelIdx + 1)
        }, 300)
      })
      .catch((err) => {
        playErrorSound()
        serverErrorMessage.value = $f.getAxiosErrMsg(err)
      })
  }
}

const onQtyForReceivedChanged = function (value: LblConfigByPda) {
  value.labelCount = Math.ceil(Number(value.qtyForReceived) / Number($d.form.qtyPCase))
}

const brandIdChanged = (value: number) => {
  if (value) {
    $f.axios.get<WmBrandDecodeRuleLite[]>('/wms/basic/brand/get-brand-decode-rule-simple-list-by-brand-id/' + value)
      .then((resp) => {
        $d.wmBrandDecodeRuleLite = resp.data
      })
      .catch((err) => {
        $f.ui.showNotifyFailed($f.getAxiosErrMsg(err))
      })
  } else {
    $d.wmBrandDecodeRuleLite = []
    $d.brandDecodeRuleId = null
    $d.scanContent = null
  }
}

const lastStep3 = () => {
  $d.workStep = 2
}

$d.nlpUrl = localStorage.getItem('nlpUrl') || ''
$d.electronicScaleUrl = localStorage.getItem('electronicScaleUrl') || ''

const focusHelper = useFocusNextHelper()
focusHelper.regRef(loc, 1)
focusHelper.regRef(qtyPIip, 2)
focusHelper.regRef(qtyPIp, 3)

const fx = $f
const e$ = $f.getFieldErrStr
</script>
